#!/usr/bin/env python
import os,sys
import threading
import Queue
import types
from wwpy.util.Logger import logger

class ThreadPool(object):
    
    def __init__(self,thread_num=4,block=True,timeout=1):
        self.threads=[]
        self.thread_num=thread_num
        self.block=block
        self.timeout=timeout
        self.in_queue=Queue.Queue()
        self.out_queue=Queue.Queue()
        self._create_threads()
        
    def _create_threads(self):
        for i in range(self.thread_num):
            thread=threading.Thread(target=self.do_job)
            thread.setDaemon(True)
            thread.start()
            self.threads.append(thread)
            
    def put(self,func,*args,**kwargs):
        self.in_queue.put((func,args,kwargs))
        
    def do_job(self):
        while True:
            try:
                func,args,kwargs=self.in_queue.get(block=self.block,timeout=self.timeout)
                thread=threading.currentThread()
                logger.info("Thread-%s is running the func %s" % (thread.ident,func.__name__))
                result=func(*args,**kwargs)
                oqargs=(thread.ident,thread.getName(),func.__name__,args,kwargs,result)
                self.out_queue.put(oqargs)
            except Queue.Empty:
                break
            except Exception:
                thread=threading.currentThread()
                logger.error("Thread-%s run func %s error:%s" % (thread.ident,func.__name__,str(sys.exc_info()[:2])))
                sys.exit()
                
    def wait(self):
        while len(self.threads)>0:
            thread=self.threads.pop()
            if thread.isAlive():
                thread.join()
            if thread.isAlive() and not self.in_queue.empty():
                self.threads.append(thread)
        logger.info("All jobs are done!")
        
    def outs(self):
        while True:
            try:
                yield self.out_queue.get(self.block,self.timeout)
            except Queue.Empty:
                break
            except:
                logger.error("Outs error:%s" % str(sys.exc_info()[:2]))
        logger.info("All jobs are out!")
        
def demo():
    def my_job(id=None,sleep=0.01):
        import urllib
        try:
            html=urllib.urlopen('http://www.58.com/').read()
            import time
            time.sleep(sleep)
        except:
            logger.error("id=%s error:%s",str(sys.exc_info()[:2]))
        return id
    tp=ThreadPool(4)
    for i in range(12):
        tp.put(my_job,i,sleep=i*0.01)
    tp.wait()
    for out in tp.outs():
        print out
    
if __name__ == '__main__':
    demo()
